package cn.chinaunicom.sdsi.frm.workflow.deployment.dao.impl;

import java.util.List;

import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import cn.chinaunicom.sdsi.frm.workflow.deployment.controller.bean.ProcessDefinitionVO;
import cn.chinaunicom.sdsi.frm.workflow.deployment.dao.ProcessDefinitionDao;

/**
 * 流程定义模块数据访问层组件
 * 
 * @author liyh
 * 
 */
@Repository("processDefinitionDao")
public class ProcessDefinitionDaoImpl implements ProcessDefinitionDao {

	private static final Log log = LogFactory
			.getLog(ProcessDefinitionDaoImpl.class);

	/**
	 * activiti工作流提供的流程存储组件
	 */
	private RepositoryService repositoryService;

	/**
	 * 根据查询条件分页查询版本最新的流程定义
	 * 
	 * @param vo
	 * @param firstResult
	 * @param maxResults
	 * @return
	 */
	@Override
	public List<ProcessDefinition> list4Page(ProcessDefinitionVO vo,
			int firstResult, int maxResults) {

		ProcessDefinitionQuery pdq = this.getRepositoryService()
				.createProcessDefinitionQuery();

		makeCondition(pdq, vo);
		log.debug("search ProcessDefinition use DAO, add condition done");

		return pdq.orderByDeploymentId().desc()
				.listPage(firstResult, maxResults);
	}

	/**
	 * 据传入参数查询符合条件的记录条数
	 * 
	 * @param vo
	 * @return
	 */
	@Override
	public long listFilteredCount(ProcessDefinitionVO vo) {
		ProcessDefinitionQuery pdq = this.getRepositoryService()
				.createProcessDefinitionQuery();

		makeCondition(pdq, vo);
		log.debug("search ProcessDefinition use DAO, get FilteredCount ");

		return pdq.count();
	}

	/**
	 * 据查询条件查询全部记录的条数
	 * 
	 * @param vo
	 * @return
	 */
	@Override
	public long listTotalCount(ProcessDefinitionVO vo) {
		ProcessDefinitionQuery pdq = this.getRepositoryService()
				.createProcessDefinitionQuery();

		log.debug("search ProcessDefinition use DAO, get TotalCount ");

		return pdq.latestVersion().count();
	}

	/**
	 * 根据流程定义文件的process查询最新发布的此流程数量
	 * 
	 * @param key
	 * @return
	 */
	@Override
	public long findNumByKey(String key) {
		long num = this.getRepositoryService().createProcessDefinitionQuery()
				.latestVersion().processDefinitionTenantId("")
				.processDefinitionKey(key).count();

		return num;
	}

	/**
	 * 根据已部署好的资源发布流程
	 * 
	 * @param resourcePath
	 * @return
	 */
	public String deploymentProcessByResource(String resourcePath) {

		String deploymentId = this.getRepositoryService().createDeployment()
				.addClasspathResource(resourcePath).deploy().getId();
		
		return deploymentId;
	}

	/**
	 * 复用拼装查询条件
	 * 
	 * @param query
	 * @return
	 */
	private ProcessDefinitionQuery makeCondition(ProcessDefinitionQuery query,
			ProcessDefinitionVO vo) {

		// 流程名称过滤
		if (!StringUtils.isBlank(vo.getName())) {
			query.processDefinitionNameLike("%" + vo.getName() + "%");
		}
		// 流程Key过滤
		if (!StringUtils.isBlank(vo.getKey())) {
			query.processDefinitionKeyLike("%" + vo.getKey() + "%");
		}
		// 流程图文件路径
		if (!StringUtils.isBlank(vo.getResourceName())) {
			query.processDefinitionResourceNameLike("%" + vo.getResourceName()
					+ "%");
		}

		return query.latestVersion();
	}

	@Autowired
	public void setRepositoryService(RepositoryService repositoryService) {
		this.repositoryService = repositoryService;
	}

	public RepositoryService getRepositoryService() {
		return repositoryService;
	}

}
